﻿using CIS.DB;
using CIS.Web.Common;
using CIS.Web.Models;
using CIS.Web.Properties;
using System;
using System.Data.Entity;
using System.Linq;
using System.Linq.Dynamic;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace CIS.Web.Controllers
{
	[RoutePrefix("ConferenceFunction")]
	public class ConferenceFunctionController : BaseDbController
	{
		[Route("Index/{ConferenceId}")]
		public async Task<ActionResult> Index(string conferenceId)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", conferenceId);

			var conferenceMaster = await DbContext.ConferenceMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.Status == ConstValues.Status.正常 &&
						x.ID == conferenceId);

			ViewBag.ConferenceId = conferenceId;
			ViewBag.ConferenceName = conferenceMaster.ConferenceName;
			ViewBag.ControllerName = Resources.ConferenceFunction;
			ViewBag.Language = conferenceMaster.IsInternational ? ConstValues.Language.En : ConstValues.Language.Cn;

			var model = new ConferenceFunctionModel();
			model.ConferenceId = conferenceId;
			LoginUser.ConferenceFunctionIdList = Utility.GetConferenceFunctionIdList(conferenceId);
			return View(model);
		}

		public async Task<JsonCamelCaseResult> GetData(int? page, int? rows, string sort, string order, ConferenceFunctionModel model)
		{
			int take = rows ?? ConstValues.DefaultGridRows;
			int skip = ((page ?? 1) - 1) * take;

			var sql = DbContext.SysFunctionMaster.AsNoTracking()
					.Where(x => x.Status == ConstValues.Status.正常 &&
						x.FunctionType == ConstValues.PageLogsType.会议 &&
						x.ID != ConstValues.FunctionId.ConferenceInfo &&
						x.ID != ConstValues.FunctionId.ConferenceFunction &&
						x.ID != ConstValues.FunctionId.ConferenceAttendenceForm &&
						x.ID != ConstValues.FunctionId.ConferenceContributeForm);

			if (!string.IsNullOrWhiteSpace(model.SelFunctionName))
			{
				sql = sql.Where(x => x.FunctionName.Contains(model.SelFunctionName) || x.Remark.Contains(model.SelFunctionName));
			}

			int total = await sql.CountAsync();

			if (!string.IsNullOrEmpty(sort))
			{
				sql = sql.OrderBy(sort + ConstValues.chrSpace + order).Skip(skip).Take(take);
			}
			else
			{
				sql = sql.OrderBy(x => x.Sort).ThenByDescending(x => x.UpdateDate).ThenBy(x => x.FunctionName).Skip(skip).Take(take);
			}

			var sqlResult = await sql.ToListAsync();

			var result = sqlResult.Select(x => new
			{
				ID = x.ID,
				FunctionName = DbContext.ConferenceMaster.AsNoTracking().FirstOrDefault(y=> y.ID == model.ConferenceId).IsInternational ? x.Remark : x.FunctionName,
				Status = DbContext.ConferenceFunctionMaster.AsNoTracking().FirstOrDefault(e => e.ConferenceId == model.ConferenceId && e.FunctionId == x.ID) != null ?
						DbContext.ConferenceFunctionMaster.AsNoTracking().FirstOrDefault(e => e.ConferenceId == model.ConferenceId && e.FunctionId == x.ID).Status :
						ConstValues.Status.暂停,
				Sort = x.Sort,
				Creator = x.Creator,
				CreateIP = x.CreateIP,
				CreateDate = Request.Cookies["_culture"].Value == ConstValues.Language.Cn ?
							x.CreateDate.Value.ToString("yyyy-MM-dd") :
							x.CreateDate.Value.ToString("MM/dd/yyyy")
			});

			return JsonCamelCase(new
			{
				Total = total,
				Rows = result,
			},
			JsonRequestBehavior.AllowGet);
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("Modify/{ConferenceId}")]
		public async Task<JsonResult> Modify(ConferenceFunctionModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var result = await DbContext.ConferenceFunctionMaster
					.FirstOrDefaultAsync(x => x.ConferenceId == model.ConferenceId &&
						x.FunctionId == model.Id);

			using (var transaction = DbContext.Database.BeginTransaction())
			{
				if (result != null)
				{
					result.Status = model.Status;
					result.Updater = LoginUser.UserName;
					result.UpdateIP = LoginUser.IP;
					result.UpdateDate = DateTime.Now;

					await this.UpdateForm(model, result);
				}
				else
				{
					var sysFunction = await DbContext.SysFunctionMaster.AsNoTracking()
							.FirstOrDefaultAsync(x => x.ID == model.Id);

					var conferenceFunctionMaster = new ConferenceFunctionMaster
					{
						ID = Utility.GetTableId(ConstValues.TableName.ConferenceFunctionMaster),
						ConferenceId = model.ConferenceId,
						FunctionId = model.Id,
						FunctionDetail = sysFunction.FunctionName,
						Sort = ConstValues.DefaultSort,
						Status = model.Status,
						Creator = LoginUser.UserName,
						CreateIP = LoginUser.IP,
						CreateDate = DateTime.Now,
					};

					DbContext.ConferenceFunctionMaster.Add(conferenceFunctionMaster);

					await this.UpdateForm(model, conferenceFunctionMaster);
				}

				await DbContext.SaveChangesAsync();
				transaction.Commit();
			}

			if (model.Status == ConstValues.Status.正常)
			{
				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessOpen), JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessClose), JsonRequestBehavior.AllowGet);
			}
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("ModifyAll/{ConferenceId}")]
		public async Task<JsonResult> ModifyAll(ConferenceFunctionModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var sysFunctionList = await DbContext.SysFunctionMaster.AsNoTracking()
					.Where(x => x.Status == ConstValues.Status.正常 &&
						x.FunctionType == ConstValues.PageLogsType.会议 &&
						x.ID != ConstValues.FunctionId.ConferenceInfo &&
						x.ID != ConstValues.FunctionId.ConferenceFunction &&
						x.ID != ConstValues.FunctionId.ConferenceAttendenceForm &&
						x.ID != ConstValues.FunctionId.ConferenceContributeForm).ToListAsync();

			using (var transaction = DbContext.Database.BeginTransaction())
			{
				var conferenceFunctionMaster = await DbContext.ConferenceFunctionMaster
						.Where(x => x.ConferenceId == model.ConferenceId).ToListAsync();
				DbContext.ConferenceFunctionMaster.RemoveRange(conferenceFunctionMaster);

				await DbContext.SaveChangesAsync();
				transaction.Commit();
			}

			using (var transaction = DbContext.Database.BeginTransaction())
			{
				var conferenceAttendenceFormList = await DbContext.ConferenceAttendenceForm
						.Where(x => x.ConferenceId == model.ConferenceId).ToListAsync();
				DbContext.ConferenceAttendenceForm.RemoveRange(conferenceAttendenceFormList);

				var conferenceContributeFormList = await DbContext.ConferenceContributeForm
						.Where(x => x.ConferenceId == model.ConferenceId).ToListAsync();
				DbContext.ConferenceContributeForm.RemoveRange(conferenceContributeFormList);

				if (model.Status == ConstValues.Status.正常)
				{
					foreach (var sysFunction in sysFunctionList)
					{
						var conferenceFunction = new ConferenceFunctionMaster
						{
							ID = Utility.GetTableId(ConstValues.TableName.ConferenceFunctionMaster),
							ConferenceId = model.ConferenceId,
							FunctionId = sysFunction.ID,
							FunctionDetail = sysFunction.FunctionName,
							Sort = sysFunction.Sort,
							Status = ConstValues.Status.正常,
							Creator = LoginUser.UserName,
							CreateIP = LoginUser.IP,
							CreateDate = DateTime.Now,
						};
						DbContext.ConferenceFunctionMaster.Add(conferenceFunction);
						await this.UpdateForm(model, conferenceFunction);
					}
				}

				await DbContext.SaveChangesAsync();
				transaction.Commit();
			}

			if (model.Status == ConstValues.Status.正常)
			{
				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessOpen), JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessClose), JsonRequestBehavior.AllowGet);
			}
		}

		private async Task UpdateForm(ConferenceFunctionModel model, ConferenceFunctionMaster result)
		{
			var conferenceMaster = await DbContext.ConferenceMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.ID == model.ConferenceId &&
						x.Status == ConstValues.Status.正常);

			#region 参会注册管理
			if (result.FunctionId == ConstValues.FunctionId.ConferenceAttendenceInfo)
			{
				var form = await DbContext.ConferenceFunctionMaster
						.FirstOrDefaultAsync(x => x.ConferenceId == model.ConferenceId &&
							x.FunctionId == ConstValues.FunctionId.ConferenceAttendenceForm);

				if (form != null)
				{
					form.Status = model.Status;
					form.Updater = LoginUser.UserName;
					form.UpdateIP = LoginUser.IP;
					form.UpdateDate = DateTime.Now;
				}
				else
				{
					if (model.Status == ConstValues.Status.正常)
					{
						var sysFunctionMaster = await DbContext.SysFunctionMaster.AsNoTracking()
								.FirstOrDefaultAsync(x => x.ID == ConstValues.FunctionId.ConferenceAttendenceForm);

						var conferenceFunctionMaster = new ConferenceFunctionMaster
						{
							ID = Utility.GetTableId(ConstValues.TableName.ConferenceFunctionMaster),
							ConferenceId = model.ConferenceId,
							FunctionId = sysFunctionMaster.ID,
							FunctionDetail = sysFunctionMaster.FunctionName,
							Sort = ConstValues.DefaultSort,
							Status = model.Status,
							Creator = LoginUser.UserName,
							CreateIP = LoginUser.IP,
							CreateDate = DateTime.Now,
						};

						DbContext.ConferenceFunctionMaster.Add(conferenceFunctionMaster);
					}
				}

				var existList = await DbContext.ConferenceAttendenceForm
						.Where(x => x.ConferenceId == model.ConferenceId).ToListAsync();
				DbContext.ConferenceAttendenceForm.RemoveRange(existList);

				if (model.Status == ConstValues.Status.正常)
				{
					var attendenceMaster = await DbContext.AttendenceMaster.AsNoTracking()
							.Where(x => x.Status == ConstValues.Status.正常).ToListAsync();

					foreach (var entity in attendenceMaster)
					{
						var conferenceAttendenceForm = new ConferenceAttendenceForm()
						{
							ID = Utility.GetTableId(ConstValues.TableName.ConferenceAttendenceForm),
							ConferenceId = model.ConferenceId,
							Key = entity.Key,
							DisplayName = conferenceMaster.IsInternational ? entity.Tip : entity.DisplayName,
							DisplayPage = entity.DisplayPage,
							Tip = string.Empty,
							IsRequired = entity.IsRequired,

							Status = entity.Status,
							Sort = entity.Sort,
							Remark = string.Empty,
							Creator = LoginUser.UserName,
							CreateIP = LoginUser.IP,
							CreateDate = DateTime.Now,
						};
						DbContext.ConferenceAttendenceForm.Add(conferenceAttendenceForm);
					}
				}
			}
			#endregion

			#region 参会投稿管理
			if (result.FunctionId == ConstValues.FunctionId.ConferenceContributeInfo)
			{
				var form = await DbContext.ConferenceFunctionMaster
						.FirstOrDefaultAsync(x => x.ConferenceId == model.ConferenceId &&
							x.FunctionId == ConstValues.FunctionId.ConferenceContributeForm);

				if (form != null)
				{
					form.Status = model.Status;
					form.Updater = LoginUser.UserName;
					form.UpdateIP = LoginUser.IP;
					form.UpdateDate = DateTime.Now;
				}
				else
				{
					if (model.Status == ConstValues.Status.正常)
					{
						var sysFunctionMaster = await DbContext.SysFunctionMaster.AsNoTracking()
								.FirstOrDefaultAsync(x => x.ID == ConstValues.FunctionId.ConferenceContributeForm);

						var conferenceFunctionMaster = new ConferenceFunctionMaster
						{
							ID = Utility.GetTableId(ConstValues.TableName.ConferenceFunctionMaster),
							ConferenceId = model.ConferenceId,
							FunctionId = sysFunctionMaster.ID,
							FunctionDetail = sysFunctionMaster.FunctionName,
							Sort = ConstValues.DefaultSort,
							Status = model.Status,
							Creator = LoginUser.UserName,
							CreateIP = LoginUser.IP,
							CreateDate = DateTime.Now,
						};

						DbContext.ConferenceFunctionMaster.Add(conferenceFunctionMaster);
					}
				}

				var existList = await DbContext.ConferenceContributeForm
						.Where(x => x.ConferenceId == model.ConferenceId).ToListAsync();
				DbContext.ConferenceContributeForm.RemoveRange(existList);

				if (model.Status == ConstValues.Status.正常)
				{
					var contributeMaster = await DbContext.ContributeMaster.AsNoTracking()
							.Where(x => x.Status == ConstValues.Status.正常).ToListAsync();

					foreach (var entity in contributeMaster)
					{
						var conferenceContributeForm = new ConferenceContributeForm()
						{
							ID = Utility.GetTableId(ConstValues.TableName.ConferenceContributeForm),
							ConferenceId = model.ConferenceId,
							Key = entity.Key,
							DisplayName = conferenceMaster.IsInternational ? entity.Tip : entity.DisplayName,
							DisplayPage = entity.DisplayPage,
							Tip = string.Empty,
							IsRequired = entity.IsRequired,

							Status = entity.Status,
							Sort = entity.Sort,
							Remark = string.Empty,
							Creator = LoginUser.UserName,
							CreateIP = LoginUser.IP,
							CreateDate = DateTime.Now,
						};
						DbContext.ConferenceContributeForm.Add(conferenceContributeForm);
					}
				}
			}
			#endregion

			#region 称呼管理
			if (result.FunctionId == ConstValues.FunctionId.ConferenceTitle)
			{
				var existList = await DbContext.TitleMaster
						.Where(x => x.ConferenceId == model.ConferenceId).ToListAsync();
				DbContext.TitleMaster.RemoveRange(existList);

				if (model.Status == ConstValues.Status.正常)
				{
					var titleList = conferenceMaster.IsInternational ? ConstValues.TitleEn : ConstValues.Title;
					foreach (var title in titleList)
					{
						var titleMaster = new TitleMaster
						{
							ID = Utility.GetTableId(ConstValues.TableName.TitleMaster),
							ConferenceId = model.ConferenceId,
							TitleName = title,
							Status = ConstValues.Status.正常,
							Sort = ConstValues.DefaultSort,
							Remark = string.Empty,
							Creator = LoginUser.UserName,
							CreateIP = LoginUser.IP,
							CreateDate = DateTime.Now
						};

						DbContext.TitleMaster.Add(titleMaster);
					}
				}
			}
			#endregion
		}
	}
}